home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /* data.c */
-
- #include <gl.h>
- #include <stdio.h>
- #include <malloc.h>
- #include "defines.h"
- #include "data.h"
-
-
- /* The root of the whole scene */
- struct node_struct *root;
-
- static void free_children(struct node_struct *child);
-
- void init_data(void)
- {
- root = make_new_node();
-
- root->node_type = ROOT;
- }
-
-
-
- /* Allocates and returns a pointer to a new patch structure */
- struct patch_struct *make_new_patch(void)
- {
- return (struct patch_struct *) malloc(sizeof(struct patch_struct));
- }
-
-
-
- /* Allocate memory for a new object node and return a pointer to it.
- * Initializes all structure elements to NULL/FALSE.
- */
- struct node_struct *make_new_node(void)
- {
- struct node_struct *new_node;
-
- new_node = (struct node_struct *) malloc(sizeof(struct node_struct));
-
- new_node->node_type = OBJECT;
- new_node->parent = NULL;
- new_node->child = NULL;
- new_node->sibling = NULL;
- new_node->prev_sibling = NULL;
- new_node->patch = NULL;
- new_node->selected = FALSE;
-
- return new_node;
- }
-
-
- struct zip_struct *make_new_zipper(void)
- {
- return (struct zip_struct *) malloc(sizeof(struct zip_struct));
- }
-
-
- struct node_struct *make_new_patch_node()
- {
- int i;
- struct node_struct *new_object;
-
- new_object = make_new_node();
- new_object->node_type = PATCH;
- new_object->patch = make_new_patch();
-
- for (i=0; i<4; i++)
- {
- new_object->patch->zipper[i] = make_new_zipper();
- new_object->patch->zipper[i]->zipped = FALSE;
- new_object->patch->zipper[i]->zip_type = NONE;
- new_object->patch->zipper[i]->patch = NULL;
- new_object->patch->zipper[i]->edge = NONE;
-
- new_object->patch->zipper[i]->s_index = NONE;
- new_object->patch->zipper[i]->s_step = 0;
- new_object->patch->zipper[i]->t_index = NONE;
- new_object->patch->zipper[i]->t_step = 0;
-
- new_object->patch->zipper[i]->i_s_index = NONE;
- new_object->patch->zipper[i]->i_s_step = 0;
- new_object->patch->zipper[i]->i_t_index = NONE;
- new_object->patch->zipper[i]->i_t_step = 0;
- }
-
-
-
- return new_object;
- }
-
-
-
-
-
- /* Attaches new_node as the last child of parent */
- void attach_node_to_parent(
- struct node_struct *new_node,
- struct node_struct *parent)
- {
- struct node_struct *last_child;
-
- new_node->parent = parent;
- new_node->sibling = NULL;
-
- if (parent->child == NULL)
- {
- new_node->prev_sibling = NULL;
- parent->child = new_node;
- }
- else
- {
- last_child = find_last_sibling(parent->child);
- last_child->sibling = new_node;
- new_node->prev_sibling = last_child;
- }
- }
-
-
-
- struct node_struct *find_last_sibling(struct node_struct *older_sibling)
- {
- if (older_sibling->sibling == NULL)
- return(older_sibling);
- else
- find_last_sibling(older_sibling->sibling);
- }
-
-
-
- /* frees the child node, as well as all its children and siblings */
- static void free_children(struct node_struct *child)
- {
- if (child != NULL)
- {
- if ((child->child != NULL) || (child->sibling != NULL))
- {
- free_children(child->child);
- free_children(child->sibling);
- }
-
- if (child->node_type == PATCH)
- {
- free((char *) child->patch->zipper[0]);
- free((char *) child->patch->zipper[1]);
- free((char *) child->patch->zipper[2]);
- free((char *) child->patch->zipper[3]);
- free((char *) child->patch);
- }
-
- free((char *) child);
- }
- }
-
-
- /* deletes an object and all its children, releasing the memory they occupied */
- void free_object(struct node_struct *object)
- {
- if (object != NULL)
- {
- if (object->node_type != PATCH)
- free_children(object->child);
- else if (object->node_type == PATCH)
- {
- unzip_all(object);
- free((char *) object->patch);
- }
-
- if (object->prev_sibling != NULL)
- object->prev_sibling->sibling = object->sibling;
- else
- object->parent->child = object->sibling;
-
- if (object->sibling != NULL)
- object->sibling->prev_sibling = object->prev_sibling;
-
-
-
- free((char *) object);
- }
- }
-
-
-
- static reattach_selected_children(
- struct node_struct *child,
- struct node_struct *parent)
- {
- struct node_struct *next_child;
-
- if (child != NULL)
- {
- next_child = child->sibling;
-
- if (child->selected)
- {
- if (child->prev_sibling == NULL)
- child->parent->child = child->sibling;
- else
- child->prev_sibling->sibling = child->sibling;
-
- if (child->sibling != NULL)
- child->sibling->prev_sibling = child->prev_sibling;
-
- child->selected = FALSE;
-
- attach_node_to_parent(child, parent);
- }
-
- reattach_selected_children(next_child, parent);
- }
- }
-
-
-
-
- /* take those children which have their selected flag set and attach under
- * a new parent node, and attch that new node to parent.
- */
- void group_selected_children(struct node_struct *parent)
- {
- struct node_struct *new_object;
-
- new_object = make_new_node();
-
- reattach_selected_children(parent->child, new_object);
-
- attach_node_to_parent(new_object, parent);
-
- new_object->selected = TRUE;
- }
-
-
- static void reassign_parent(
- struct node_struct *child,
- struct node_struct *parent)
- {
- if (child != NULL)
- {
- child->parent = parent;
- reassign_parent(child->sibling, parent);
- }
- }
-
- static void attach_grandchildren_to_parent(
- struct node_struct *grandchild,
- struct node_struct *parent)
- {
- struct node_struct *last_child;
-
- if (grandchild != NULL)
- {
- last_child = find_last_sibling(parent->child);
-
- last_child->sibling = grandchild;
- grandchild->prev_sibling = last_child;
-
- reassign_parent(grandchild, parent);
- }
- }
-
-
-
-
-
-
- /* for each object node (not patch node) that is selected, detach it
- * and reattach it to the child's parent. Then remove the child.
- */
- void ungroup_selected_children(struct node_struct *child)
- {
- struct node_struct *next_child;
-
- if (child != NULL)
- {
- next_child = child->sibling;
-
- if ((child->selected) && (child->node_type == OBJECT))
- {
- attach_grandchildren_to_parent(child->child,child->parent);
- child->child = NULL;
-
- free_object(child);
- }
-
- ungroup_selected_children(next_child);
- }
- }
-
-
-
-
- struct node_struct *find_rootmost_parent(struct node_struct *child)
- {
- if (child != NULL)
- {
- if (child->parent == root)
- return child;
- else
- return( find_rootmost_parent(child->parent));
- }
- else
- {
- fprintf(stderr, "Uh Oh. Got a null node in find_rootmost_parent\n");
- exit(0);
- }
- }
-
-
-
-
-
-